<?php
/**
 * Auctioneer data file parser
 *
 * This file contains the code that converts Auctioneer data from LUA to a PHP
 * class. The class in this file requiers the WLP_Parser class.
 *
 * @author David Stangeby <david.stangeby@gmail.com>
 * @version 0.1
 * @package WLP
 * @copyright  Copyright (c) 2005-2009 Arctic Solutions (http://www.arcticsolutions.no/)
 * @license    http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt GNU General Public License v2
 */

/**
 * Include the WLP_Parser class file
 */
require_once(dirname(__FILE__) . '/../AucParser.php');

/**
 * Class that gets Auctineer data from a LUA data file
 *
 * @package WLP
 */
class WLP_Auctioneer_Scanner
{
    /**
     * The WLP_Parser instance.
     * @var WLP_Parser
     */
    protected $parser;
    
    /**
     * The array containing the Auctioneer data
     * @var array
     */
    protected $data = array();
    
    /**
     * Database handle for inserting the Auctioneer data to a database
     * @var WLP_Db_Interface
     */
    protected $db;
    
    /**
     * Number of rows to parse before saving to database and clearing
     * @var integer
     */
    protected $buffer = 1000;
    
    /**
     * To use low memory mode or not.
     * @var bool
     */
    protected $lowMemory = false;
    
    /**
     * Amount of rows processed.
     * @var integer
     */
    protected $rowsProcessed = 0;
    
    /**
     * Constructor
     *
     * Creates a new instance of the WLP_Parser class, and then parses
     * the input file. After that it extracts the Auctioneer data.
     *
     * @param mixed $input Array, file or string to be parsed
     * @param WLP_Db_Interface $db Database object for saving the data to a database
     * @param bool $lowMemory If set to true uses low memory mode, clearing data as its written to the database
     * @return WLP_Scan
     */
    public function __construct($input, WLP_Db_Interface $db = null, $lowMemory = false)
    {
        if($db instanceof WLP_Db_Interface) {
            $this->db = $db;
        }
        if($lowMemory) {
            $this->lowMemory = true;
        }
        $this->parser = new Auc_WLP_Parser($input);
        $this->extractData();
        return $this;
    }
    
    /**
     * Returns the data array
     *
     * @return array
     */
    public function toArray()
    {
        return $this->data;
    }
    
    /**
     * Unsets the data array with all the rows from the Auctionner data file.
     * This clears up it's memory usage, as it can get quite high.
     *
     * @return void
     */
    public function unsetData()
    {
        unset($this->data);
    }
    
    /**
     * Extracts and saves the Auctioneer data to the data array.
     *
     * @return void
     */
    protected function extractData()
    {
        $luaArray = $this->parser->toArray();
        if($this->lowMemory) {
            unset($this->parser);
        }
        $scanRows = array();
        $scanRow = array();
        foreach($luaArray['AucDbData']['scans'] as $realm => $scans) {
			$realm = preg_replace("/(\w*)\/([a-zA-Z ']*)-(\w*)/i","$2 - $3",$realm);
            if(isset($this->db)) {
                $scanRow['realm'] = $this->getRealmId($realm);
            }
            foreach($scans as $timestamp => $scan) {
                if(empty($scan)) {
                    continue;
                }
                $scanRow['timestamp'] = $timestamp;
                $scanRows = explode(';', $scan);
                foreach($scanRows as $row) {
					set_time_limit(10);
					//ob_flush();
                    list($scanRow['itemid'],
                         $scanRow['itemsuffix'],
                         $scanRow['itemenchant'],
                         $scanRow['itemfactor'],
                         $scanRow['itemseed'],
                         $scanRow['stacksize'],
                         $scanRow['sellername'],
                         $scanRow['minbid'],
                         $scanRow['buyoutprice'],
                         $scanRow['curbid'],
                         $scanRow['timeleft']) = explode(':', $row);
                    $this->data[$realm][] = $scanRow;
                    $this->rowsProcessed++;
                    $this->doLowMemoryWrites();
                }
                $this->doLowMemoryWrites(true);
            }
        }
        if(isset($this->db)) {
            $this->writeToDatabase();
            if($this->lowMemory) {
                unset($this->data);
            }
        }
    }
    
    /**
     * Returns the array from the parser.
     *
     * @return Array
     */
    public function parserToArray()
    {
        return $this->parser->toArray();
    }
    
    /**
     * Gets the realm id from the database, if id is not found it makes a new one
     *
     * @param string $realm
     * @return interger
     */
    protected function getRealmId($realm)
    {
        if(!$id = $this->db->getItem('realms', array('id'), 'name = '.$this->db->quote($realm))) {
            return $this->db->insertItem('realms', array('name' => $realm));
        }
        return $id['id'];
    }
    
    /**
     * Does low memory database writes if enabled and buffer is buildt up.
     *
     * @param bool $overrrideBuffer Does the database writes even if buffer isn't built up
     * @return void;
     */
    protected function doLowMemoryWrites($overrrideBuffer = false)
    {
        if($this->lowMemory
           && ($this->rowsProcessed >= $this->buffer || $overrrideBuffer)
           && isset($this->db)) {
            $this->writeToDatabase();
            $this->data = array();
            $this->rowsProcessed = 0;
        }
    }
    
    /**
     * Writes the data variable to a database.
     *
     * @return void
     */
    protected function writeToDatabase()
    {
        foreach($this->data as $realm => $rows) {
            $this->db->insertItems('scans', $rows);
        }
    }
}